package com.xu.finalshell.activation.util;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

/**
 * @author xuguan
 * @since 2024/6/18
 */
public class DigestUtil {
    private static final String MD5_ALGORITHM_NAME = "MD5";
    private static final String KECCAK384_ALGORITHM_NAME = "Keccak-384";
    private static final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    public static String md5Hex(String input) {
        return digestHex(input, MD5_ALGORITHM_NAME);
    }

    public static String keccak384Hex(String input) {
        Security.addProvider(new BouncyCastleProvider());
        return digestHex(input, KECCAK384_ALGORITHM_NAME);
    }

    private static String digestHex(String input, String algorithm) {
        MessageDigest digest = getDigest(algorithm);
        final byte[] digestBytes = digest.digest(input.getBytes(StandardCharsets.UTF_8));
        return toHex(digestBytes);
    }

    private static MessageDigest getDigest(String algorithm) {
        try {
            return MessageDigest.getInstance(algorithm);
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalArgumentException("illegal algorithm [" + algorithm + "]", e);
        }
    }

    private static String toHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        for (byte b : bytes) {
            sb.append(HEX_CHARS[b >>> 4 & 0x0f])
                    .append(HEX_CHARS[b & 0x0f]);
        }
        return sb.toString();
    }
}
